﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace net.xBei.Helper;
/// <summary>
/// MD5的快捷操作
/// </summary>
public static class Md5Helper {
    /// <summary>
    /// MD5编码（16位小写）
    /// </summary>
    /// <param name="text"></param>
    /// <returns>返回16位小写</returns>
    public static string MD5Encrypt16(this string text) => Md5Encrypt16(text, System.Text.Encoding.UTF8);
    /// <summary>
    /// 计算MD5（32位小写）
    /// </summary>
    /// <param name="text"></param>
    /// <param name="times">重复几次</param>
    /// <returns>返回32位小写</returns>
    public static string MD5Encrypt(this string text, int times = 1) {
        var max = Math.Max(times, 1);
        for (var i = 1; i <= max; i++) {
            text = MD5Encrypt(Encoding.UTF8.GetBytes(text));
        }
        return text;
    }

    /// <summary>
    /// MD5编码
    /// </summary>
    /// <param name="buffer"></param>
    /// <returns>返回32位小写</returns>
    public static string MD5Encrypt(this IEnumerable<byte> buffer) => MD5Encrypt(buffer.ToArray());
    /// <summary>
    /// 获取文件的Md5编码
    /// </summary>
    /// <param name="filePath"></param>
    /// <returns>返回32位小写</returns>
    public static string FileMD5Encrypt(this string filePath) => MD5Encrypt(File.OpenRead(filePath));

    #region MD5加密
    /// <summary>
    /// 获取文件的MD5
    /// </summary>
    /// <param name="input"></param>
    /// <returns>返回32位小写</returns>
    public static string MD5EncryptFile(string input) => MD5Encrypt(File.OpenRead(input));

    /// <summary>
    /// 计算MD5
    /// </summary>
    /// <param name="input">需要加密的数据</param>
    /// <returns>返回32位小写</returns>
    public static string MD5Encrypt(this byte[] input) {
        var t = MD5.HashData(input);
        return Convert.ToHexString(t).ToLower();
        //var sb = new StringBuilder(32);
        //for (var i = 0; i < t.Length; i++)
        //    sb.Append(t[i].ToString("x2"));
        //return sb.ToString();
    }
    /// <summary>
    /// 计算数据流的MD5
    /// </summary>
    /// <param name="stream"></param>
    /// <returns>返回32位小写</returns>
    public static string MD5Encrypt(this Stream stream) {
        using var md5Serv = MD5.Create();
        var buffer = md5Serv.ComputeHash(stream);
        return Convert.ToHexString(buffer).ToLower();
        //var sb = new StringBuilder();
        //foreach (var var in buffer)
        //    sb.Append(var.ToString("x2"));
        //return sb.ToString();
    }

    private static string Md5Encrypt16(string input, Encoding encode)
        => Convert.ToHexString(MD5.HashData(encode.GetBytes(input)), 4, 8).ToLower();
    #endregion
}
